﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LowLevelGraphics.VideoFormats
{
    /// <summary>
    /// Avi reader
    /// 
    /// instantiate AVI reader
    /// AVIReader reader = new AVIReader( );
    /// open video 
    /// filereader.Open( "test.avi" );
    /// read the video file
    /// while ( reader.Position - reader.Start < reader.Length )
    /// {
    /// get next frame
    ///Bitmap image = reader.GetNextFrame( );
    /// .. process the frame somehow or display it
    /// }
    /// reader.Close( );
    /// </summary>
    public class AviReader : IDisposable
    {
        protected int m_nFirstFrame = -1;
        protected int m_nFrameRate = -1;
        protected int m_nLength = -1;
        protected string m_sCodec = string.Empty;

        protected IntPtr m_ptrGetFrame = IntPtr.Zero;
        protected IntPtr m_ptrStream = IntPtr.Zero;
        protected IntPtr m_ptrFile = IntPtr.Zero;

        /// <summary>
        /// Initializes a new instance of the <see cref="AviReader"/> class.
        /// </summary>
        public AviReader()
        {
            CGraphics.AVIFileInit();
        }

        /// <summary>
        /// Opens the specified _s file name.
        /// </summary>
        /// <param name="_sFileName">Name of the _s file.</param>
        /// <returns></returns>
        public bool Open(string _sFileName)
        {
            IntPtr ptrAviFile = IntPtr.Zero;
            CGraphics.AVIFileOpen(out ptrAviFile, _sFileName, CGraphics.OpenFileMode.Read, IntPtr.Zero);
            return false;
        }

        /// <summary>
        /// Closes this instance.
        /// </summary>
        public void Close()
        {
            lock (this)
            {
                //// release get frame object
                if (m_ptrGetFrame != IntPtr.Zero)
                {
                    CGraphics.AVIStreamGetFrameClose(m_ptrGetFrame);
                    m_ptrGetFrame = IntPtr.Zero;
                }

                // release stream
                if (m_ptrStream != IntPtr.Zero)
                {
                    CGraphics.AVIStreamRelease(m_ptrStream);
                    m_ptrStream = IntPtr.Zero;
                }

                // release file
                if (m_ptrFile != IntPtr.Zero)
                {
                    CGraphics.AVIFileRelease(m_ptrFile);
                    m_ptrFile = IntPtr.Zero;
                }
            }
        }

        /// <summary>
        /// Gets the first frame.
        /// </summary>
        /// <value>The first frame.</value>
        public int FirstFrame
        {
            get { return m_nFirstFrame; }
        }

        /// <summary>
        /// Gets the length.
        /// </summary>
        /// <value>The length.</value>
        public int Length
        {
            get { return m_nLength; }
        }

        /// <summary>
        /// Gets the frame rate.
        /// </summary>
        /// <value>The frame rate.</value>
        public int FrameRate
        {
            get { return m_nFrameRate; }
        }

        /// <summary>
        /// Gets the codec.
        /// </summary>
        /// <value>The codec.</value>
        public string Codec
        {
            get { return m_sCodec; }
        }

        #region IDisposable Members

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            CGraphics.AVIFileExit();
        }

        /// <summary>
        /// Dispose the object.
        /// </summary>
        /// 
        /// <param name="disposing">Indicates if disposing was initiated manually.</param>
        /// 
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                // dispose managed resources
            }
            // close current AVI file if any opened and uninitialize AVI library
            Close();
            CGraphics.AVIFileExit();
        }

        ~AviReader()
        {
            Dispose( false );
        }

        #endregion
    }
}
